package com.seed.core.pojo.seed;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.seed.core.action.Action;
import com.seed.core.column.Column;
import com.seed.core.enumeration.SeedType;
import com.seed.core.listener.OnSaveListener;
import com.seed.core.listener.OnSetListener;
import com.seed.core.listener.OnUpdateListener;

import java.util.*;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Seed {
    private String name;
    private String tableName;
    private String tableSchema;
    private SeedType type;
    private String label;
    private String comment;
    private String nameColumn; // 一般是name字段

    private Map<String, Action> actions; // 键为请求方法+功能名称，形如： 【GET actionName】
    private LinkedHashMap<String, Column> columns; // 键为列名称
    private LinkedHashMap<String, Relation> relations;

    private List<? extends OnSaveListener> onSave; // 保存时的事件监听
    private List<? extends OnUpdateListener> onUpdate; // 更新时的事件监听
    private List<? extends OnSetListener> onSet; // 查询时的事件监听

    private List<String> declares; // 功能所需要的数据列
    private List<String> searches; // 如果是功能是page或list，这里申明对应的搜索拦，形如：name_like,age_eq等
    private List<String> orders; // 排序
    private Map<String, Stat> stats; // 统计

    private Boolean checkLogin; // 是否需要检查登录
    private Boolean checkAction; // 是否需要检查功能权限

    public Seed copy() {
        Seed ret = new Seed();
        ret.setName(name);
        ret.setTableName(tableName);
        ret.setTableSchema(tableSchema);
        ret.setType(type);
        ret.setLabel(label);
        ret.setComment(comment);
        ret.setNameColumn(nameColumn);

        if(actions != null) {
            Map<String, Action> newActions = new HashMap<>();
            for(Map.Entry<String, Action> entry: actions.entrySet()) {
                Action action = entry.getValue();
                newActions.put(entry.getKey(), action.copy());
            }
            ret.setActions(newActions);
        }

        if(columns != null) {
            LinkedHashMap<String, Column> newColumns = new LinkedHashMap<>();
            for(Map.Entry<String, Column> entry: columns.entrySet()) {
                newColumns.put(entry.getKey(), entry.getValue().copy());
            }
            ret.setColumns(newColumns);
        }

        if(relations != null) {
            LinkedHashMap<String, Relation> newRelations = new LinkedHashMap<>();
            for(Map.Entry<String, Relation> entry: relations.entrySet()) {
                newRelations.put(entry.getKey(), entry.getValue().clone());
            }
            ret.setRelations(newRelations);
        }

        if(onSave != null) ret.setOnSave(new ArrayList<>(onSave));
        if(onUpdate != null) ret.setOnUpdate(new ArrayList<>(onUpdate));
        if(onSet != null) ret.setOnSet(new ArrayList<>(onSet));

        if(declares != null) ret.setDeclares(new ArrayList<>(declares));
        if(searches != null) ret.setSearches(new ArrayList<>(searches));
        if(orders != null) ret.setOrders(new ArrayList<>(orders));
        if(stats != null) ret.setStats(stats);

        ret.setCheckLogin(checkLogin);
        ret.setCheckAction(checkAction);
//        ret.setCheckData(checkData);
//        ret.setCheckField(checkField);
//        ret.setUseKeyword(useKeyword);

        return ret;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableSchema() {
        return tableSchema;
    }

    public void setTableSchema(String tableSchema) {
        this.tableSchema = tableSchema;
    }

    public SeedType getType() {
        return type;
    }

    public void setType(SeedType type) {
        this.type = type;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public String getNameColumn() {
        return nameColumn;
    }

    public void setNameColumn(String nameColumn) {
        this.nameColumn = nameColumn;
    }

    public Map<String, Action> getActions() {
        return actions;
    }

    public void setActions(Map<String, Action> actions) {
        this.actions = actions;
    }

    public LinkedHashMap<String, Column> getColumns() {
        return columns;
    }

    public void setColumns(LinkedHashMap<String, Column> columns) {
        this.columns = columns;
    }

    public LinkedHashMap<String, Relation> getRelations() {
        return relations;
    }

    public void setRelations(LinkedHashMap<String, Relation> relations) {
        this.relations = relations;
    }

    public List<? extends OnSaveListener> getOnSave() {
        return onSave;
    }

    public void setOnSave(List<? extends OnSaveListener> onSave) {
        this.onSave = onSave;
    }

    public List<? extends OnUpdateListener> getOnUpdate() {
        return onUpdate;
    }

    public void setOnUpdate(List<? extends OnUpdateListener> onUpdate) {
        this.onUpdate = onUpdate;
    }

    public List<? extends OnSetListener> getOnSet() {
        return onSet;
    }

    public void setOnSet(List<? extends OnSetListener> onSet) {
        this.onSet = onSet;
    }

    public List<String> getDeclares() {
        return declares;
    }

    public void setDeclares(List<String> declares) {
        this.declares = declares;
    }

    public List<String> getSearches() {
        return searches;
    }

    public void setSearches(List<String> searches) {
        this.searches = searches;
    }

    public List<String> getOrders() {
        return orders;
    }

    public void setOrders(List<String> orders) {
        this.orders = orders;
    }

    public Map<String, Stat> getStats() {
        return stats;
    }

    public void setStats(Map<String, Stat> stats) {
        this.stats = stats;
    }

    public Boolean getCheckLogin() {
        return checkLogin;
    }

    public void setCheckLogin(Boolean checkLogin) {
        this.checkLogin = checkLogin;
    }

    public Boolean getCheckAction() {
        return checkAction;
    }

    public void setCheckAction(Boolean checkAction) {
        this.checkAction = checkAction;
    }

//    public Boolean getCheckData() {
//        return checkData;
//    }
//
//    public void setCheckData(Boolean checkData) {
//        this.checkData = checkData;
//    }
//
//    public Boolean getCheckField() {
//        return checkField;
//    }
//
//    public void setCheckField(Boolean checkField) {
//        this.checkField = checkField;
//    }
//
//    public Boolean getUseKeyword() {
//        return useKeyword;
//    }
//
//    public void setUseKeyword(Boolean useKeyword) {
//        this.useKeyword = useKeyword;
//    }
}
